home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / dev / gui / gui4cli.lha / Gui4Cli / Ext / LVFormat / rewrap.h < prev    next >
Encoding:
Text File  |  1999-06-16  |  7.1 KB  |  281 lines

  1.  
  2. // ==============================================================
  3. // Rewrap a listview
  4. // - construct a new list with the line lengths wanted and
  5. //      replace & kill the old one.
  6. // gcm     = struct *GCmain (from where we get the lv pointer)
  7. // length = the new line length wanted
  8. // hdchars = the chars which will be considered as header
  9. // justmode = 1=justify, 2=unjustijy, 3=center, 0=leave alone
  10. // ==============================================================
  11.  
  12. rewrap (struct GCmain *gcm, LONG length, UBYTE *hdchars, SHORT justmode,
  13.     struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  14. {
  15.     LONG     lh=0, c=0, lastc=0;
  16.     struct List      *ls, *lst;
  17.     struct fulist *fls;
  18.     struct lister *fl, *nextfl;
  19.     UBYTE     *buff, *p, *b, *lastp, *lastb;
  20.     UBYTE     *head, *h, *jbf;
  21.     BOOL     just=0, unjust=0, center=0, reset=0, flag=0;
  22.  
  23.     // get pointer to current listview
  24.     if (!(fls = gcm->curlv) || !fls->ls || IsListEmpty(fls->ls)) 
  25.          return (0);
  26.     
  27.     // get working buffers, check they're long enough
  28.     if (gcm->buffsize < (length - 2)) return (0);
  29.     buff = gcm->membuff[0];
  30.     head = gcm->membuff[1]; // for line header
  31.     jbf  = gcm->membuff[2]; // for justification
  32.  
  33.     // set justify flags
  34.     if          (justmode == 1) { just=1; unjust=1; }
  35.     else if (justmode == 2) unjust=1;
  36.     else if (justmode == 3) { center=1; unjust=1; } 
  37.     else if (justmode == 4) { reset=1; unjust=1; }
  38.  
  39.     // prepare a new list struct
  40.     if (!(lst = getlist(SysBase, DOSBase))) return (0);
  41.     // unattach old list - attach new
  42.     ls = fls->ls; fls->ls = lst;
  43.     fls->maxlength = fls->maxnow = fls->totnum = 0;
  44.     fls->curpt = NULL; fls->line    = -1;
  45.  
  46.     fl = (struct lister *)(ls->lh_Head); // point to 1st rec
  47.  
  48.     // skip any blank lines at beginning
  49.     while ((nextfl = (struct lister *)(fl->node.ln_Succ)) && !flag)
  50.     {     if (fl->start[0] == '\0')
  51.          {        addline (fls, "", 0, SysBase, DOSBase);
  52.                 fl = nextfl;
  53.          }
  54.          else flag = 1;
  55.     }
  56.  
  57.     // get 1st leading indent
  58.     p = lastp = fl->start;
  59.     for (lh=0, h=head; (lh<length) && *p && ((*p==' ') || isin(*p, hdchars)); ++p, ++h, ++lh)
  60.          *h = *p;
  61.     *h = '\0';
  62.     if (reset)    
  63.     {     c=0;     *buff='\0';  b=lastb=buff;    }
  64.     else
  65.     {     c=lh; strcpy (buff, head);
  66.          b = lastb = &buff[lh];
  67.     }
  68.  
  69.     // do the whole list..
  70.     while (nextfl = (struct lister *)(fl->node.ln_Succ))
  71.     {
  72.         while (*p)
  73.         {
  74.             // mark last space or line breakable char encountered
  75.             if (*p==' ')
  76.             {
  77.                 if (unjust)     // delete spaces if unjust on
  78.                 {    while (p[1]==' ') ++p;
  79.                     if (b==buff) ++p; // if at the start of a line..
  80.                 }
  81.                 lastp = p;
  82.                 lastb = b;
  83.                 lastc = c;
  84.             }
  85.  
  86.             // copy char
  87.             *b = *p;
  88.             ++b; ++p; ++c;
  89.              
  90.             // if we're over the length, change line..
  91.             if (c >= length)
  92.             {
  93.                   if (lastb == &buff[lh])     // line unbroken - force break
  94.                   {  lastp = p;
  95.                       lastc = c;
  96.                       lastb = b;
  97.                   }
  98.                   else
  99.                 p = lastp;
  100.                 
  101.                 // if (*p == ' ') ++p;
  102.                 while (*p==' ') ++p;
  103.                 *lastb = '\0';
  104.  
  105.                 // if justify is on..
  106.                 if (just)
  107.                 {    c = justify (buff, &buff[lh], jbf, length, SysBase, DOSBase);
  108.                     addline (fls, jbf, c, SysBase, DOSBase);
  109.                 }
  110.                 else if (center)
  111.                 {    c = centertxt (buff, &buff[lh], jbf, length, SysBase, DOSBase);
  112.                     addline (fls, jbf, c, SysBase, DOSBase);
  113.                 }
  114.                 else
  115.                     addline (fls, buff, lastc, SysBase, DOSBase);
  116.  
  117.                 // reinitiate line head buffer
  118.                 if (reset)
  119.                 {     c=0; *buff='\0'; b=lastb=buff; }
  120.                 else
  121.                 {     strcpy (buff, head);
  122.                      b = lastb = &buff[lh];
  123.                      c = lh;
  124.                 }
  125.             
  126.             }     // end of new line handling
  127.  
  128.         }     // end of while (*p)
  129.  
  130.         // (!*p) == end of line..
  131.  
  132.         if (!nextfl->node.ln_Succ)                      // end of file
  133.         {
  134.              *b = '\0';
  135.              if (center)
  136.              {     c = centertxt (buff, &buff[lh], jbf, length, SysBase, DOSBase);
  137.                    addline (fls, jbf, c, SysBase, DOSBase);
  138.              }
  139.              else 
  140.                  addline (fls, buff, c, SysBase, DOSBase);
  141.              goto endwrap;
  142.         }
  143.         else if (nextfl->start[0] == '\0')          // a paragraph..
  144.         {
  145.              *b = '\0';
  146.              if (center)
  147.              {     c = centertxt (buff, &buff[lh], jbf, length, SysBase, DOSBase);
  148.                    addline (fls, jbf, c, SysBase, DOSBase);
  149.              }
  150.              else 
  151.                    addline (fls, buff, c, SysBase, DOSBase);
  152.  
  153.              fl = nextfl;
  154.              nextfl = (struct lister *)(fl->node.ln_Succ);
  155.              // add a blank line
  156.              addline (fls, "", 0, SysBase, DOSBase);
  157.              // goto next line..
  158.              fl = nextfl;
  159.  
  160.              // reinitiate head buffer
  161.              p = lastp = fl->start;
  162.              for (lh=0, h=head; (lh<length) && *p && ((*p==' ') || isin(*p, hdchars)); ++p, ++h, ++lh)
  163.                   *h = *p;
  164.              *h = '\0';
  165.              if (reset)     
  166.              {      c=0;  *buff='\0';    b=lastb=buff;     }
  167.              else
  168.              {      c=lh; strcpy (buff, head);
  169.                   b = lastb = &buff[lh];
  170.              }
  171.         }
  172.         // otherwise skip it
  173.         else 
  174.         {     fl = nextfl;
  175.              // reinitiate head buffer
  176.              p = lastp = fl->start;
  177.              for (lh=0, h=head; (lh<length) && *p && ((*p==' ') || isin(*p, hdchars)); p++, h++, lh++)
  178.                   *h = *p;
  179.              *h = '\0';
  180.              *b = ' ';        // insert a space at line end
  181.              lastb = b;
  182.              lastc = c;
  183.              ++b; ++c; 
  184.         }
  185.  
  186.     }    // end of main while loop
  187.  
  188.     endwrap:
  189.     // our new list is ready - free the old one
  190.     freelist (ls, SysBase, DOSBase);
  191.  
  192.     return (1); // ok..
  193. }
  194.  
  195. // ==============================================================
  196. // do justify
  197. // Justify *str into *buff which should become length long
  198. // hdrend is the end of the line header
  199. // ==============================================================
  200. LONG justify (UBYTE *str, UBYTE *hdrend, UBYTE *buff, LONG length,
  201.             struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  202. {
  203.     LONG spaces, len=0, add=0, fill, c, step=0, stepcount=0, bal=0;
  204.     UBYTE *p, *buffstart;
  205.     buffstart = buff;
  206.  
  207.     // count spaces in str & it's length
  208.     for (p=str; *p && (p < hdrend); ++p, ++len); // go past header
  209.     for (spaces=0; *p; ++p, ++len) if (*p==' ') ++spaces;
  210.  
  211.     // the number of characters we have to add
  212.     fill = length - len;
  213.     if (spaces) 
  214.     {    // num of spaces to add to each space (probably 0)
  215.         add = fill / spaces;
  216.         // also add a space every <step> chars
  217.         bal = fill - (spaces * add); // how many chars left
  218.         if (bal)
  219.             step = spaces / bal;     // add space every step chars
  220.     }
  221.  
  222.     while (*str)
  223.     {     if ((*str == ' ') && (str > hdrend))
  224.          {
  225.              *buff = ' ';
  226.              ++buff;
  227.              for (c=0; c<add; ++c) {  *buff=' '; ++buff; }
  228.              ++stepcount;
  229.              if ((stepcount == step) && bal)
  230.              {     *buff=' '; ++buff;
  231.                  stepcount = 0;
  232.                  --bal;
  233.              }
  234.          }
  235.          else 
  236.          {     *buff=*str; 
  237.              ++buff;
  238.          }
  239.          ++str;
  240.     }
  241.     *buff = '\0';
  242.     return ((LONG)(buff - buffstart));
  243. }
  244.  
  245.  
  246. // ==============================================================
  247. // Center text
  248. // Center *str into *buff for a line length long
  249. // hdrend is the end of the line header
  250. // ==============================================================
  251. LONG centertxt (UBYTE *str, UBYTE *hdrend, UBYTE *buff, LONG length,
  252.             struct ExecBase *SysBase, struct DosLibrary *DOSBase)
  253. {
  254.     LONG    linelen, actlen, addlen, hdrlen;
  255.     UBYTE *p, *b;
  256.  
  257.     hdrlen = (LONG)(hdrend - str);
  258.     linelen = length - hdrlen;
  259.     actlen  = strlen(str) - hdrlen;
  260.     addlen  = (linelen - actlen) / 2; // the No of spaces to be added each side
  261.  
  262.     b = buff;
  263.     while (str < hdrend)        // copy header
  264.     {     *b = *str;
  265.          ++b; ++str;
  266.     }
  267.     while (addlen)                // copy left spaces
  268.     {     *b=' ';     ++b;
  269.          --addlen;
  270.     }
  271.     while (*str)                // copy the text
  272.     {     *b = *str;
  273.          ++b; ++str;
  274.     }
  275.     *b = '\0';
  276.     return ((LONG)(b - buff));
  277. }
  278.  
  279.  
  280.  
  281.